WebAssembly基本上是設計成一個基於堆疊的虛擬機,所以跟指令息息相關的就是堆疊的操作。這通常並不是直接用程式操作堆疊,而使每個指令的輸入與輸出,都是透過堆疊。傳參數給指令,是把值推入堆疊,然後指令根據需要從堆疊取出,最後再把結果推入堆疊。
不過,常常會碰到某個參數要先計算,某個後計算,然後才傳給指令等比較複雜的狀況,在腦袋裡直接推演目前這行程式的堆疊狀態有時會碰到困難。所以WebAssembly的文字格式,也支援S-Expression語法。S-Expression是用「前序式」的語法,括號之後接指令,指令之後接參數,先後計算的順序,可以透過括號來表達,這樣會比較清楚。
指令 | 參數 | 返回 | 說明 |
---|---|---|---|
i32.load8_s | (位址) | i32 | 從記憶體載入1位元組資料,延伸成32位元有號整數 |
i32.load8_u | (位址) | i32 | 從記憶體載入1位元組資料,延伸成32位元無號整數 |
i32.load16_s | (位址) | i32 | 從記憶體載入2位元組資料,延伸成32位元有號整數 |
i32.load16_u | (位址) | i32 | 從記憶體載入2位元組資料,延伸成32位元無號整數 |
i32.load | (位址) | i32 | 從記憶體載入4位元組資料成為32位元整數 |
i64.load8_s | (位址) | i64 | 從記憶體載入1位元組資料,延伸成64位元有號整數 |
i64.load8_u | (位址) | i64 | 從記憶體載入1位元組資料,延伸成64位元無號整數 |
i64.load16_s | (位址) | i64 | 從記憶體載入2位元組資料,延伸成64位元有號整數 |
i64.load16_u | (位址) | i64 | 從記憶體載入2位元組資料,延伸成64位元無號整數 |
i64.load16_s | (位址) | i64 | 從記憶體載入4位元組資料,延伸成64位元有號整數 |
i64.load16_u | (位址) | i64 | 從記憶體載入4位元組資料,延伸成64位元無號整數 |
i64.load | (位址) | i64 | 從記憶體載入8位元組資料成為64位元整數 |
f32.load | (位址) | f32 | 從記憶體載入4位元資料成為32位元浮點數 |
f64.load | (位址) | f64 | 從記憶體載入8位元資料成為64位元浮點數 |
指令 | 參數 | 返回 | 說明 |
---|---|---|---|
i32.store8 | (位址) (值) | 無 | 把32位元整數包裝成1位元組存回記憶體 |
i32.store16 | (位址) (值) | 無 | 把32位元整數包裝成2位元組存回記憶體 |
i32.store | (位址) (值) | 無 | 把32位元整數包裝成4位元組存回記憶體 |
i64.store8 | (位址) (值) | 無 | 把64位元整數包裝成1位元組存回記憶體 |
i64.store16 | (位址) (值) | 無 | 把64位元整數包裝成2位元組存回記憶體 |
i64.store32 | (位址) (值) | 無 | 把64位元整數包裝成4位元組存回記憶體 |
i64.store | (位址) (值) | 無 | 把64位元整數包裝成8位元組存回記憶體 |
f32.store | (位址) (值) | 無 | 把32位元浮點數包裝成4位元組存回記憶體 |
f64.store | (位址) (值) | 無 | 把64位元浮點數包裝成8位元組存回記憶體 |
目前版本的WebAssembly使用i32來定址,所以能使用最大的記憶體只能到4GB。
指令 | 參數 | 返回 | 說明 |
---|---|---|---|
grow_memory | (大小) | 無 | 把記憶體大小增加指定的頁數(每頁64KB) |
current_memory | 無 | (頁數) | 取得目前記憶體大小(單位:頁數) |
指令 | 參數 | 返回 | 說明 |
---|---|---|---|
get_local (名稱 or 索引) | 無 | 變數值 | 取得指定變數的值 |
set_local (名稱 or 索引) | (值) | 無 | 設定變數值 |
tee_local (名稱 or 索引) | (值) | 設定的值 | 設定變數值並返回 |
指令 | 參數 | 返回 | 說明 |
---|---|---|---|
get_global (名稱 or 索引) | 無 | 變數值 | 取得指定變數的值 |
set_global (名稱 or 索引) | (值) | 無 | 設定變數值 |
指令 | 參數 | 返回 | 說明 |
---|---|---|---|
i32.const (數值) | 無 | 指定的數值 | 回傳指定數值的32位元整數常數 |
i64.const (數值) | 無 | 指定的數值 | 回傳指定數值的64位元整數常數 |
f32.const (數值) | 無 | 指定的數值 | 回傳指定數值的32位元浮點數常數 |
f64.const (數值) | 無 | 指定的數值 | 回傳指定數值的64位元浮點數常數 |
指令 | 參數 | 返回 | 說明 |
---|---|---|---|
i32.add | (參數1) (參數2) | 計算結果 | 計算參數1加上參數2的結果 |
i32.sub | (參數1) (參數2) | 計算結果 | 計算參數1減去參數2的結果 |
i32.mul | (參數1) (參數2) | 計算結果 | 計算參數1乘以參數2的結果 |
i32.div_s | (參數1) (參數2) | 計算結果 | 計算參數1除以參數2的結果(有號) |
i32.div_u | (參數1) (參數2) | 計算結果 | 計算參數1除以參數2的結果(無號) |
i32.rem_s | (參數1) (參數2) | 計算結果 | 計算參數1除以參數2的餘數(有號) |
i32.rem_u | (參數1) (參數2) | 計算結果 | 計算參數1除以參數2的餘數(無號) |
指令 | 參數 | 返回 | 說明 |
---|---|---|---|
i32.and | (參數1) (參數2) | 計算結果 | 回傳兩個參數and運算結果 |
i32.or | (參數1) (參數2) | 計算結果 | 回傳兩個參數or運算結果 |
i32.xor | (參數1) (參數2) | 計算結果 | 回傳兩個參數xor運算結果 |
i32.shl | (參數1) (參數2) | 計算結果 | 回傳參數1向左移參數2所指定個位元的運算結果 |
i32.shr_s | (參數1) (參數2) | 計算結果 | 回傳參數1向右移參數2所指定個位元的運算結果(有號) |
i32.shr_u | (參數1) (參數2) | 計算結果 | 回傳參數1向右移參數2所指定個位元的運算結果(無號) |
i32.rotl | (參數1) (參數2) | 計算結果 | 回傳參數1向左旋轉參數2所指定個位元的運算結果 |
i32.rotr | (參數1) (參數2) | 計算結果 | 回傳參數1向右旋轉參數2所指定個位元的運算結果 |
指令 | 參數 | 返回 | 說明 |
---|---|---|---|
i32.eq | (參數1) (參數2) | 比較結果 | 參數1與參數2是否相等 |
i32.ne | (參數1) (參數2) | 比較結果 | 參數1與參數2是否不相等 |
i32.lt_s | (參數1) (參數2) | 比較結果 | 參數1是否小於參數2(有號) |
i32.le_s | (參數1) (參數2) | 比較結果 | 參數1是否小於或等於參數2(有號) |
i32.lt_u | (參數1) (參數2) | 比較結果 | 參數1是否小於參數2(無號) |
i32.le_u | (參數1) (參數2) | 比較結果 | 參數1是否小於或等於參數2(無號) |
i32.gt_s | (參數1) (參數2) | 比較結果 | 參數1是否大於參數2(有號) |
i32.ge_s | (參數1) (參數2) | 比較結果 | 參數1是否大於或等於參數2(有號) |
i32.gt_u | (參數1) (參數2) | 比較結果 | 參數1是否大於參數2(無號) |
i32.ge_u | (參數1) (參數2) | 比較結果 | 參數1是否大於或等於參數2(無號) |
i32.eqz | (參數1) | 比較結果 | 參數1為0時返回1,否則返回0 |
比較運算的結果,都是32位元整數,1代表true,0代表false
指令 | 參數 | 返回 | 說明 |
---|---|---|---|
i32.clz | (參數1) | 結果 | 返回參數1作為二進位數字開頭的0的數目 |
i32.ctz | (參數1) | 結果 | 返回參數1作為二進位數字結尾的0的數目 |
i32.popcnt | (參數1) | 結果 | 返回參數1作為二進位數字中所有的1的數目 |
運算子跟32位元一樣。
32位元整數運算已經有的,這裡就不列出。IEEE754的浮點數是有帶號的,所以不會區分有號或無號的運算。
指令 | 參數 | 返回 | 說明 |
---|---|---|---|
f32.abs | (參數1) | 結果 | 將參數1改成正值 |
f32.neg | (參數1) | 結果 | 將參數1的符號反向(正->負,負->正) |
f32.copysign | (參數1) (參數2) | 結果 | 將參數1的數值與參數2的符號合成結果 |
f32.ceil | (參數1) | 結果 | 將參數1無條件進位成整數 |
f32.floor | (參數1) | 結果 | 將參數1無條件捨味成整數 |
f32.trunc | (參數1) | 結果 | 將參數1的小數捨去,成為更趨近0的整數 |
f32.nearest | (參數1) | 結果 | 將參數1四捨五入 |
f32.sqrt | (參數1) | 結果 | 取得參數1的平方根 |
f32.min | (參數1) (參數2) | 結果 | 回傳較小的 |
f32.max | (參數1) (參數2) | 結果 | 回傳較大的 |
也都跟32位元浮點數一樣,只是是64位元運算。
整理差不多,剩下轉型用的指令,明天再看好了...